/*
******************************************************************************************************* 
**  Copyright (C) 2019, 苏州检易生物科技有限公司 
**  All rights reserved. 
** 
**  FileName:       	comm_stack.c
**  Description:	common comunication protocol	简称ccp
**  Author:        	 
**  Version				v0.1
**  Date:           	2019-07-19
**	Function List： 
**  History:         
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                              	调试开关
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                             INCLUDE FILES
*********************************************************************************************************
*/
#include "log_console.h"
#include "template_list.h"
#include <rthw.h>



/*
*********************************************************************************************************
*                                              	宏定义
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                              	结构体定义
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                              	函数原型声明
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                              	全局变量定义
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*                                              	模块静态变量定义
*********************************************************************************************************
*/
//static ccp_list_t 	s_send_list;				//待发送队列
//static ccp_list_t	s_ack_wait_list;			//发送后等待应答队列


/*
*********************************************************************************************************
*                                              	函数定义
*********************************************************************************************************
*/
list_err_t list_create(list_t* p_list, uint16_t max_size ,list_io_type type, void* p_mem)
{
	ASSERT(p_list);
	ASSERT(p_mem);
	ASSERT(max_size != 0);
	ASSERT(type <= LIST_FILO);
//	if(max_size == 0 || node_size < sizeof(void*) || type > LIST_FILO)
//	{
//		return LIST_ERR_CREAT;
//	}
	p_list->cur_size 	= 0;
	p_list->type 			= type;
	p_list->max_size	= max_size;
	p_list->head 			= NULL;
	p_list->tail			= NULL;
	p_list->rt_mp			= (struct rt_mempool*)p_mem;
	
//	OS_ERR os_err;
////	void* p_mem = malloc(max_size * node_size);
////	if(p_mem == NULL)
////		return LIST_ERR_CREAT;
//	OSMemCreate(&p_list->os_mem, "list mem", (void*)p_list->p_mem, p_list->max_size, p_list->node_size, &os_err);
//	if(os_err != OS_ERR_NONE)
//		return LIST_ERR_CREAT;
	return LIST_ERR_NONE;
}

void* list_new(list_t* p_list)
{
	ASSERT(p_list);
	void* p_new = rt_mp_alloc(p_list->rt_mp,RT_WAITING_FOREVER);
	return p_new;
}

list_err_t list_push(list_t* p_list, void* p_node)
{
	ASSERT(p_list);
	ASSERT(p_node);
	if(p_list->cur_size == p_list->max_size)
	{
		Critical_Log("List full at %08X;\r\n",p_list);
		return LIST_ERR_PUSH;
	}
	rt_base_t it = rt_hw_interrupt_disable();
	
	((list_node_t*)p_node)->next = NULL;
	if(p_list->cur_size == 0)
	{
		p_list->head = (list_node_t*)p_node;
		p_list->tail = (list_node_t*)p_node;
	}
	else
	{
		p_list->tail->next = (list_node_t*)p_node;
		p_list->tail = (list_node_t*)p_node;
	}
	p_list->cur_size++;
	rt_hw_interrupt_enable(it);
	return LIST_ERR_NONE;
}

void* list_pop(list_t* p_list)
{
	ASSERT(p_list);
	list_node_t* p_rtn = NULL;
		
	
	if(p_list->cur_size == 0)
		return NULL;
	rt_base_t it = rt_hw_interrupt_disable();
	
	if(p_list->cur_size == 1)
	{
		p_rtn = p_list->head;
		p_list->head = NULL;
		p_list->tail = NULL;
		p_list->cur_size = 0;
		rt_hw_interrupt_enable(it);
		return p_rtn;
	}
	
	if(p_list->type == LIST_FIFO)
	{
		p_rtn = p_list->head;
		p_list->head = p_list->head->next;
		p_list->cur_size--;
	}
	else if(p_list->type == LIST_FILO)
	{
		list_node_t* p_tmp = p_list->head;
		while(p_tmp->next->next != NULL)
		{
			p_tmp = p_tmp->next;
		}
		p_rtn = p_tmp->next;
		p_tmp->next = NULL;
		p_list->tail = p_tmp;
		p_list->cur_size--;
	}
	else
	{
		rt_hw_interrupt_enable(it);
		return NULL;
	}
	rt_hw_interrupt_enable(it);
	return p_rtn;
	
}

list_err_t list_free(list_t* p_list, list_node_t* p_node)
{
	ASSERT(p_list);
	ASSERT(p_node);
	rt_mp_free(p_node);
	return LIST_ERR_FREE;
}

/*删除一个链表中的节点*/
list_err_t list_remove(list_t* p_list, list_node_t* p_node)
{
	ASSERT(p_list);
	ASSERT(p_node);
	list_node_t* p_tmp;
	rt_base_t it = rt_hw_interrupt_disable();
	
	if(p_list->cur_size <= 1)
	{
		p_tmp = p_list->head;
		if(p_tmp == p_node)
		{
			p_list->cur_size = 0;
			p_list->head = NULL;
			p_list->tail = NULL;
			rt_hw_interrupt_enable(it);
			return list_free(p_list,p_node);
		}
	}
	else
	{
		p_tmp = p_list->head;
		if(p_tmp == p_node)
		{
			p_list->head = p_list->head->next;
			p_list->cur_size--;
			rt_hw_interrupt_enable(it);
			return list_free(p_list,p_node);
		}
		else
		{
			while(p_tmp->next != NULL)
			{
				if(p_tmp->next == p_node)
					break;
				p_tmp = p_tmp->next;
			}
			if(p_tmp->next == p_node)
			{
				p_tmp->next = p_node->next;
				if(p_node == p_list->tail)
					p_list->tail = p_tmp;
				p_list->cur_size--;
				rt_hw_interrupt_enable(it);
				return list_free(p_list,p_node);
			}
		}
	}
}
list_err_t list_clear(list_t* p_list)
{
	ASSERT(p_list);
	rt_base_t it = rt_hw_interrupt_disable();
	
	list_node_t* p_next = p_list->head;
	list_node_t* p_tmp = p_next;
	while(p_next != NULL)
	{
		p_tmp = p_next;
		rt_mp_free(p_next);
		p_next = p_tmp->next;
	}
	p_list->cur_size = 0;
	p_list->head = NULL;
	p_list->tail = NULL;
	rt_hw_interrupt_enable(it);
	return LIST_ERR_NONE;
}


